package com.ruoyi.system.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.exception.GlobalException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.system.domain.BdmCloudInventory;
import com.ruoyi.system.domain.BdmGood;
import com.ruoyi.system.domain.BdmMemberRule;
import com.ruoyi.system.domain.BdmUser;
import com.ruoyi.system.domain.dto.importDto.BdmGoodsImportDto;
import com.ruoyi.system.domain.dto.importDto.BdmUserImportDto;
import com.ruoyi.system.mapper.*;
import com.ruoyi.system.service.*;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.*;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

@Service
public class BdmFileImportServiceImpl implements IBdmFileImportService {

    @Autowired
    private IBdmUserService bdmUserService;

    @Autowired
    private ISysUserService sysUserService;

    @Autowired
    private IBdmMemberRuleService bdmMemberRuleService;

    @Autowired
    private IBdmMemberLevelService bdmMemberLevelService;

    //获取事务
    @Autowired
    private SqlSessionTemplate sqlSessionTemplate;

    @Autowired
    private IBdmGoodService bdmGoodService;

    @Autowired
    private IBdmCloudInventoryService bdmCloudInventoryService;
    /**
     * 导入用户信息
     */
    @Override
    @Transactional
    public void importUserInfo(MultipartFile file) {
        if (file.isEmpty()) {
            throw new GlobalException("上传的文件为空");
        }
        ExcelUtil<BdmUserImportDto> util = new ExcelUtil<>(BdmUserImportDto.class);

        int count = 2;
        try {
            // 查询全部用户
            Map<String, SysUser> sysUserMap = sysUserService.selectUserList(new SysUser())
                    .stream().collect(Collectors.toMap(SysUser::getPhonenumber, s -> s));

            Map<String, Integer> levelMap = new HashMap<>();
            bdmMemberLevelService.lambdaQuery().list().forEach(level ->{
                levelMap.put(level.getMemberLevelName(), level.getMemberLevelType());
            });
            List<BdmUser> bdmUserList = new ArrayList<>();
            List<BdmMemberRule> memberRuleList = new ArrayList<>();

            SqlSession sqlSession = sqlSessionTemplate.getSqlSessionFactory().openSession(ExecutorType.BATCH, false);
            SysUserMapper sysUserMapper = sqlSession.getMapper(SysUserMapper.class);
            List<BdmUserImportDto> importDtoList = util.importExcel(file.getInputStream());
            int batchSize = 1000; // 每批次处理的数据量
            try {
                if (StringUtils.isNotEmpty(importDtoList)) {
                    for (BdmUserImportDto importDto : importDtoList) {
                        // 只保存 数据库没有的用户
                        if (ObjectUtil.isEmpty(sysUserMap.get(importDto.getPhoneNumber()))) {
                            SysUser sysUser = new SysUser();
                            sysUser.setUserName(importDto.getRealName());
                            sysUser.setPhonenumber(importDto.getPhoneNumber());
                            sysUser.setNickName(importDto.getNickname());
                            sysUser.setCreateTime(importDto.getJoinTime());
                            sysUser.setUpdateTime(DateUtils.getNowDate());
                            sysUser.setRemark("导入用户");
                            sysUser.setUserType("01");
                            sysUser.setPassword(SecurityUtils.encryptPassword("123456"));
                            sysUserMapper.insertUser(sysUser);
                        }
                        count++;

                        // 每达到一批次大小时，提交事务并清空缓存
                        if (count % batchSize == 0) {
                            sqlSession.commit();
                            sqlSession.clearCache();
                        }
                    }
                }
                // 最后一批不足 1000 的数据也需要提交
                if (count % batchSize != 0) {
                    sqlSession.commit();
                    sqlSession.clearCache();
                }
            } catch (Exception e) {
                sqlSession.rollback();
                throw new RuntimeException(e.getMessage());
            } finally {
                sqlSession.close();
            }

            // 上级用户
            List<SysUser> sysUserList = sysUserService.selectUserList(new SysUser());
            Map<String, SysUser> userMap = new HashMap<>();
            if (CollectionUtil.isNotEmpty(sysUserList)) {
                sysUserList.forEach(user -> {
                    userMap.put(user.getPhonenumber(), user);
                });
            }
            for (BdmUserImportDto importDto : importDtoList) {
                // 只保存 数据库没有的用户
                if (ObjectUtil.isEmpty(sysUserMap.get(importDto.getPhoneNumber()))) {
                    SysUser sysUser = userMap.get(importDto.getPhoneNumber());
                    BdmUser user = new BdmUser();
                    user.setSysUserid(sysUser.getUserId());
                    // 上级用户
                    // 分销奖励上级用户
                    if (ObjectUtil.isNotEmpty(importDto.getSuperiorPhoneNumber())
                            && !Objects.equals(importDto.getPhoneNumber(), String.valueOf(importDto.getSuperiorPhoneNumber()))) {
                        SysUser u = userMap.get(importDto.getSuperiorPhoneNumber()+"");
                        user.setParentId(ObjectUtil.isNotEmpty(u) ? u.getUserId() : null);
                        user.setDistributionParentId(ObjectUtil.isNotEmpty(u) ? u.getUserId() : null);
                    }

                    user.setUserPhone(importDto.getPhoneNumber());
                    user.setCreateTime(importDto.getJoinTime());
                    user.setStatus(1L);
                    user.setRemainingSum(importDto.getBalance());
                    user.setEarnings(importDto.getCommission());
                    user.setIfNewUser(2L);
                    bdmUserList.add(user);

                    // 建立 会员等级
                    BdmMemberRule memberRule = new BdmMemberRule();
                    memberRule.setSysUserid(sysUser.getUserId());
                    Integer i = levelMap.getOrDefault(importDto.getMemberLevel().toUpperCase(Locale.US), 0);
                    if (StringUtils.isNotEmpty(importDto.getMemberLevel())) {
                        if (i != 0) {
                            memberRule.setMemberLevel(Long.valueOf(i));
                        } else if (!importDto.getMemberLevel().contains("普通会员")) {
                            memberRule.setMemberLevel(1L);
                            memberRule.setMemberName("vip");
                            if (Pattern.compile("联|创").matcher(importDto.getMemberLevel()).find()) {
                                memberRule.setMemberAgencyLevel(4L);
                                memberRule.setMemberAgencyLevelName("联创");
                            } else if (Pattern.compile("共享").matcher(importDto.getMemberLevel()).find()) {
                                memberRule.setMemberAgencyLevel(3L);
                                memberRule.setMemberAgencyLevelName("共享店主");
                            } else if (Pattern.compile("运营").matcher(importDto.getMemberLevel()).find()) {
                                memberRule.setMemberAgencyLevel(5L);
                                memberRule.setMemberAgencyLevelName("运营");
                            } else if (Pattern.compile("总裁").matcher(importDto.getMemberLevel()).find()) {
                                memberRule.setMemberAgencyLevel(6L);
                                memberRule.setMemberAgencyLevelName("总裁");
                            }
                        }
                    }
                    memberRule.setCreateTime(DateUtils.getNowDate());
                    if (!importDto.getMemberLevel().contains("普通会员")) {
                        memberRuleList.add(memberRule);
                    }
                }
            }

            if (CollectionUtil.isNotEmpty(bdmUserList)) {
                bdmUserService.saveBatch(bdmUserList);
            }
            if (CollectionUtil.isNotEmpty(memberRuleList)) {
                bdmMemberRuleService.saveBatch(memberRuleList);
            }
        } catch (IOException e) {
            e.printStackTrace();
            throw new GlobalException("文件读取错误" + "  " + e.getMessage() + " -- " + count);
        }
    }

    @Transactional
    public void importUserInfo2(MultipartFile file) throws IOException {
        if (file.isEmpty()) {
            throw new GlobalException("上传的文件为空");
        }
        ExcelUtil<BdmUserImportDto> util = new ExcelUtil<>(BdmUserImportDto.class);
        List<BdmUserImportDto> importDtoList = util.importExcel(file.getInputStream());
        Thread t1 = new Thread(() -> {
            for (BdmUserImportDto dto : importDtoList) {
                SysUser sysUser = new SysUser();
                sysUser.setUserName(dto.getRealName());
                sysUser.setPhonenumber(dto.getPhoneNumber());
                sysUser.setNickName(dto.getNickname());
                sysUser.setCreateTime(dto.getJoinTime());
                sysUser.setUpdateTime(DateUtils.getNowDate());
                sysUser.setRemark("导入用户");
                sysUser.setUserType("01");
                sysUser.setPassword(SecurityUtils.encryptPassword("123456"));
                sysUser.setStatus("0");
                sysUser.setDelFlag("0");
                sysUser.setUserId(Long.valueOf(dto.getUserId()));
                sysUserService.insertUser(sysUser);
            }
        });
        Thread t2 = new Thread(() -> {
            for (BdmUserImportDto dto : importDtoList) {
                BdmUser bdmUser = new BdmUser();
                bdmUser.setSysUserid(Long.valueOf(dto.getUserId()));
                List<BdmUserImportDto> dtoList = importDtoList.stream().filter(f -> f.getPhoneNumber().equals(dto.getSuperiorPhoneNumber())).collect(Collectors.toList());
                if (!CollectionUtils.isEmpty(dtoList)) {
                    bdmUser.setParentId(Long.valueOf(dtoList.get(0).getUserId()));
                    bdmUser.setDistributionParentId(Long.valueOf(dtoList.get(0).getUserId()));
                }
                bdmUser.setUserPhone(dto.getPhoneNumber());
                bdmUser.setCreateTime(dto.getJoinTime());
                bdmUser.setStatus(1L);
                bdmUser.setRemainingSum(dto.getBalance());
                bdmUser.setEarnings(dto.getCommission());
                bdmUser.setIfNewUser(2L);
                bdmUserService.insertBdmUser(bdmUser);
            }
        });
        Thread t3 = new Thread(() -> {
            for (BdmUserImportDto dto : importDtoList) {

                BdmMemberRule memberRule = new BdmMemberRule();
                if (!dto.getMemberLevel().contains("普通用户")){
                    if (dto.getMemberLevel().contains("VIP")) {
                        memberRule.setMemberLevel(1L);
                        memberRule.setMemberName("VIP");
                    }
                    if (dto.getMemberLevel().contains("SVIP")) {
                        memberRule.setMemberLevel(2L);
                        memberRule.setMemberName("SVIP");
                    }
                    if (dto.getMemberLevel().contains("联创")) {
                        memberRule.setMemberAgencyLevel(4L);
                        memberRule.setMemberAgencyLevelName("联创");
                    }  if (dto.getMemberLevel().contains("共享店主")) {
                        memberRule.setMemberAgencyLevel(3L);
                        memberRule.setMemberAgencyLevelName("共享店主");
                    }  if (dto.getMemberLevel().contains("运营")) {
                        memberRule.setMemberAgencyLevel(5L);
                        memberRule.setMemberAgencyLevelName("运营");
                    }  if (dto.getMemberLevel().contains("总裁")) {
                        memberRule.setMemberAgencyLevel(6L);
                        memberRule.setMemberAgencyLevelName("总裁");
                    }
                    memberRule.setCreateTime(DateUtils.getNowDate());
                    memberRule.setState(1L);
                    memberRule.setSysUserid(Long.valueOf(dto.getUserId()));
                    bdmMemberRuleService.insertBdmMemberRule(memberRule);
                }
            }
        });
        t1.start();
        t2.start();
        t3.start();
    }

    /**
     * 导入库存数据
     */
    @Override
    public void importInventoryInfo(MultipartFile file) {
        if (ObjectUtils.isEmpty(file)){
            throw new RuntimeException("请上传文件");
        }
        XSSFWorkbook workbook =null;
        try {
            workbook=new XSSFWorkbook(file.getInputStream());
        } catch (IOException e) {
            e.printStackTrace();
            throw new RuntimeException("创建工作簿失败");
        }
        Sheet sheet = workbook.getSheetAt(0);

        int lastRowNum = sheet.getLastRowNum();
        if (lastRowNum==1){
            throw new RuntimeException("请填写数据");
        }

        //获取全部用户
        Map<String, BdmUser> bdmUserMaps = bdmUserService.lambdaQuery()
                .list().stream().collect(Collectors.toMap(BdmUser::getUserPhone, u -> u));

        // 获取全部商品
        Map<Long, BdmGood> bdmGoodMap = bdmGoodService.lambdaQuery()
                .list().stream().collect(Collectors.toMap(BdmGood::getId, good -> good));

        //查询用户库存信息
        Map<Long, List<BdmCloudInventory>> bdmCloudInventoryMaps = bdmCloudInventoryService.lambdaQuery()
                .list().stream().collect(Collectors.groupingBy(BdmCloudInventory::getUserId));

        // 会员等级
        Map<Long, BdmMemberRule> memberRuleMaps = bdmMemberRuleService.lambdaQuery()
                .list().stream().collect(Collectors.toMap(BdmMemberRule::getSysUserid, m -> m));

        // 新增或修改
        List<BdmCloudInventory> insertOrUpdateList = new ArrayList<>();

        Row row0 = sheet.getRow(0);
        int lastCellNum = row0.getLastCellNum(); // 共有多少列

        List<Long> goodIdList = new ArrayList<>();
        for (int i = 5; i < lastCellNum; i++) {
            goodIdList.add(Long.valueOf(row0.getCell(i).getStringCellValue().substring(4)));
        }

        for (int i = 1; i < lastRowNum; i++) {
            Row row = sheet.getRow(i);

            Cell phoneCell = row.getCell(2);
            String phone = getCellValueAsString(phoneCell);
            Cell levelCell = row.getCell(3);
            String level = levelCell.getStringCellValue();
            BdmUser user = bdmUserMaps.get(phone);
            if ( ObjectUtils.isEmpty(user) ){
                continue;
            }
            Long userId = user.getSysUserid();
            BdmMemberRule memberRule = memberRuleMaps.get(userId);
            if (ObjectUtils.isEmpty(memberRule) || ObjectUtils.isEmpty(memberRule.getMemberAgencyLevel())
                    || ObjectUtils.isEmpty(memberRule.getMemberAgencyLevelName())){
                continue;
            }
            List<BdmCloudInventory> cloudList = bdmCloudInventoryMaps.get(userId);
            Map<Long, BdmCloudInventory> map = new HashMap<>();
            if (CollectionUtil.isNotEmpty(cloudList)) {
                map = cloudList.stream().collect(Collectors.toMap(BdmCloudInventory::getGoodId, b -> b));
            }
            for (int j = 5; j < lastCellNum; j++) {
                Cell cell = row.getCell(j);
                if (ObjectUtils.isEmpty(cell)){
                    continue;
                }
                double cellValue = cell.getNumericCellValue();
                long integerPart = (long) cellValue;
                if (ObjectUtil.isEmpty(integerPart)
                        || integerPart == 0L){
                    continue;
                }
                Long goodId = goodIdList.get(j-5);
                BdmCloudInventory cloud = map.get(goodId);
                if (ObjectUtil.isNotEmpty(cloud)) {
                    cloud.setGoodInventory(new BigDecimal(cloud.getGoodInventory()).add(BigDecimal.valueOf(integerPart)).toString());
                    cloud.setUpdateTime(DateUtils.getNowDate());
                    insertOrUpdateList.add(cloud);
                }else {
                    BdmGood bdmGood = bdmGoodMap.get(goodId);
                    if (ObjectUtil.isEmpty(bdmGood)) {
                        continue;
                    }
                    BdmCloudInventory clouds = new BdmCloudInventory();
                    clouds.setUserId(userId);
                    clouds.setGoodId(goodId);
                    clouds.setGoodImg(bdmGood.getGoodImg());
                    clouds.setGoodName(bdmGood.getGoodName());
                    BigDecimal stock = BigDecimal.ZERO;
                    if (level.contains("总裁")) {
                        stock = ObjectUtil.isNotEmpty(bdmGood.getPresidentPrice()) ? bdmGood.getPresidentPrice() : stock;
                    }else if(level.contains("区域运营中心")) {
                        stock = ObjectUtil.isNotEmpty(bdmGood.getOperationsPrice()) ? bdmGood.getOperationsPrice() : stock;
                    }else if(level.contains("联创")) {
                        stock = ObjectUtil.isNotEmpty(bdmGood.getJoinPrice()) ? bdmGood.getJoinPrice() : stock;
                    }else if(level.contains("共享店主")) {
                        stock = ObjectUtil.isNotEmpty(bdmGood.getSharePrice()) ? bdmGood.getSharePrice() : stock;
                    }else if(level.contains("SVIP")) {
                        stock = ObjectUtil.isNotEmpty(bdmGood.getSvipPrice()) ? bdmGood.getSvipPrice() : stock;
                    } else {
                        stock = ObjectUtil.isNotEmpty(bdmGood.getVipPrice()) ? bdmGood.getVipPrice() : stock;
                    }
                    clouds.setStockPrice(stock);
                    clouds.setRetailPrice(bdmGood.getRetailPrice());
                    clouds.setProfit(clouds.getRetailPrice().subtract(clouds.getStockPrice()));
                    clouds.setGoodInventory(String.valueOf(integerPart));
                    clouds.setCreateTime(DateUtils.getNowDate());
                    clouds.setCreateBy(SecurityUtils.getUserId().toString());
                    insertOrUpdateList.add(clouds);
                }
            }
        }

        try{
            if (CollectionUtil.isNotEmpty(insertOrUpdateList)) {
                bdmCloudInventoryService.saveOrUpdateBatch(insertOrUpdateList);
            }
        }catch (Exception e){
            e.printStackTrace();
            throw new RuntimeException("导入失败");
        }finally {
            try {
                workbook.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 根据单元格类型获取其值并转换为字符串
     *
     * @param cell 单元格对象
     * @return 单元格的字符串值
     */
    private static String getCellValueAsString(Cell cell) {
        switch (cell.getCellType()) {
            case STRING:
                return cell.getStringCellValue();
            case NUMERIC:
                if (org.apache.poi.ss.usermodel.DateUtil.isCellDateFormatted(cell)) {
                    // 如果是日期格式，转换为字符串
                    return cell.getDateCellValue().toString();
                } else {
                    // 否则，假设它是数字并转换为字符串
                    // 对于电话号码，可能需要去掉小数点后多余的零
                    return String.format(Locale.ROOT, "%.0f", cell.getNumericCellValue());
                }
            case BOOLEAN:
                return String.valueOf(cell.getBooleanCellValue());
            case FORMULA:
                // 可以选择处理公式的结果，这里直接返回公式结果的字符串表示
                return cell.getCellFormula();
            default:
                return "";
        }
    }
}
